#pragma once
#include<WS2TCPIP.H>
#include <mstcpip.h>
#include<winsock2.h>
#include <string>
#include "Delegate.h"

DECLARE_MULTICAST_DELEGATE(FOnICMPResultSignature, char*, bool);

//ip头部，每个变量含义请参考ip首部格式，注意编译器对结构体优化的问题，详细情况，请看http://blog.csdn.net/u012198947/article/details/51078214里面的说明
typedef struct _iphdr
{
    unsigned char h_lenver;
    unsigned char tos;
    unsigned short total_len;
    unsigned short ident;
    unsigned short frag_and_flags;
    unsigned char ttl;
    unsigned char proto;
    unsigned short checksum;
    unsigned int sourceIP;
    unsigned int destIP;
}IPHEADER;

//icmp头部
typedef struct _icmphdr
{
    BYTE i_type;
    BYTE i_code;
    USHORT i_cksum;
    USHORT i_id;
    USHORT i_seq;
    ULONG timestamp;
}ICMPHEADER;

//解码结果
typedef struct
{
    USHORT usSeqNo;		  //包序列号
    DWORD dwRoundTripTime; //往返时间
    in_addr dwIPaddr;	  //对端IP地址
} DECODE_RESULT;//ip头部定义，具体含义，参考ip头部格式

class ICMPScanner
{
public:
    ICMPScanner();

    void SendRequest(unsigned long DestIP);
    void SendRequest(const char* DestIPStr);

    FOnICMPResultSignature OnResult;

private:
    void Init();
    USHORT CheckSum(USHORT* buffer, int size);
    int SendEchoRequest(SOCKET s, LPSOCKADDR_IN lpstToAddr);
    BOOL DecodeIcmpResponse(char* pBuf, int iPacketSize, DECODE_RESULT& stDecodeResult);
    DWORD RecvEchoReply(SOCKET s, SOCKADDR_IN* saFrom, SOCKADDR_IN* saDest, DECODE_RESULT* stDecodeResult);

private:
    SOCKET sockRaw;
};
